/*
 * Copyright (c) 2020-2021 YangZeLin. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 *    of conditions and the following disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 *    to endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "target_config.h"
#include "los_typedef.h"
#include <unistd.h>
#include "stdlib.h"
#include "stdio.h"
#include "los_process_pri.h"
#include "disk.h"
#include "sys/mount.h"
#include "los_rootfs.h"

#include "los_config.h"
#include "gic_common.h"
#include "los_printf.h"
#include "los_smp.h"
#include "los_vm_map.h"
#include "los_vm_zone.h"
#include "los_vm_boot.h"
#include "los_mmu_descriptor_v6.h"
#include "los_init.h"

#include "mtd_partition.h"

#ifdef LOSCFG_FS_VFS
#include "disk.h"
#endif
#include "los_rootfs.h"
#ifdef LOSCFG_SHELL
#include "shell.h"
#include "shcmd.h"
#endif

#ifdef LOSCFG_DRIVERS_MEM
#include "los_dev_mem.h"
#endif

#ifdef LOSCFG_DRIVERS_HDF
#include "devmgr_service_start.h"
#endif

#include "los_task.h"

UINT32 OsRandomStackGuard(VOID)
{
#ifdef LOSCFG_DRIVERS_RANDOM
    UINT32 stackGuard = 0;

    HiRandomHwInit();
    (VOID)HiRandomHwGetInteger(&stackGuard);
    HiRandomHwDeinit();
    return stackGuard;
#else
    return 0;
#endif
}

#ifdef LOSCFG_DRIVERS_MEM
int mem_dev_register(void)
{
    return DevMemRegister();
}
#endif

VOID HalClockIrqClear(VOID) {}

int mount_rootfs(void)
{
    int ret = 0;

    ret = add_mtd_partition("spinor", 0, 0x800000, 0);
    if (ret) {
        dprintf("add_mtd_partition fail.");
        return ret;
    }

    dprintf("mount /dev/spinorblk0 / ...\n");
    if (mount("/dev/spinorblk0", "/", "jffs2", 0, NULL))
    {
        PRINT_ERR("mount failed.\n");
    }

    return 0;
}

void SystemInit(void)
{
#ifdef LOSCFG_DRIVERS_MEM
	dprintf("mem dev init ...\n");
	extern int mem_dev_register(void);
	mem_dev_register();
#endif

	dprintf("Date:%s.\n", __DATE__);
	dprintf("Time:%s.\n", __TIME__);

#ifdef LOSCFG_DRIVERS_HDF
	dprintf("DeviceManagerStart start ...\n");
	if (DeviceManagerStart()) {
		PRINT_ERR("No drivers need load by hdf manager!");
	}
	dprintf("DeviceManagerStart end ...\n");
#endif

#ifdef LOSCFG_PLATFORM_ROOTFS
    dprintf("OsMountRootfs start ...\n");
    mount_rootfs();
    dprintf("OsMountRootfs end ...\n");
#endif

#ifdef LOSCFG_DRIVERS_HDF_PLATFORM_UART
    if (virtual_serial_init(TTY_DEVICE) != 0) {
        PRINT_ERR("virtual_serial_init failed");
    }
    if (system_console_init(SERIAL) != 0) {
        PRINT_ERR("system_console_init failed\n");
    }
#endif

    if (OsUserInitProcess()) {
        PRINT_ERR("Create user init process faialed!\n");
        return;
    }
    dprintf("cat log shell end\n");
    return;
}

#ifdef LOSCFG_KERNEL_MMU
LosArchMmuInitMapping g_archMmuInitMapping[] = {
    {
        .phys = SYS_MEM_BASE,
        .virt = KERNEL_VMM_BASE,
        .size = KERNEL_VMM_SIZE,
        .flags = MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS,
        .name = "KernelCached",
    },
    {
        .phys = SYS_MEM_BASE,
        .virt = UNCACHED_VMM_BASE,
        .size = UNCACHED_VMM_SIZE,
        .flags = MMU_INITIAL_MAP_NORMAL_NOCACHE,
        .name = "KernelUncached",
    },
    {
        .phys = PERIPH_PMM_BASE,
        .virt = PERIPH_DEVICE_BASE,
        .size = PERIPH_DEVICE_SIZE,
        .flags = MMU_INITIAL_MAP_DEVICE,
        .name = "PeriphDevice",
    },
    {
        .phys = PERIPH_PMM_BASE,
        .virt = PERIPH_CACHED_BASE,
        .size = PERIPH_CACHED_SIZE,
        .flags = MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS,
        .name = "PeriphCached",
    },
    {
        .phys = PERIPH_PMM_BASE,
        .virt = PERIPH_UNCACHED_BASE,
        .size = PERIPH_UNCACHED_SIZE,
        .flags = MMU_INITIAL_MAP_STRONGLY_ORDERED,
        .name = "PeriphStronglyOrdered",
    },
    {
        .phys = DDR_RAMFS_ADDR,
        .virt = DDR_RAMFS_VBASE,
        .size = DDR_RAMFS_SIZE,
        .flags = MMU_INITIAL_MAP_DEVICE,
        .name = "Sbull",
    },
    {
        .phys = GIC_PHY_BASE,
        .virt = GIC_VIRT_BASE,
        .size = GIC_VIRT_SIZE,
        .flags = MMU_INITIAL_MAP_DEVICE,
        .name = "GIC",
    },
    {0}
};
#endif
